<template>
	<n-layout has-sider style="height: 100vh;">
		<!--侧边栏-->
		<n-layout-sider
			class="shadow-md"
			width="16rem"
			:native-scrollbar="false"
			:collapsed-width="64"
			collapse-mode="width"
			:collapsed="menuCollapsed">
			<div class="flex-shrink-0 w-full h-16 flex justify-center items-center">
				<!--折叠菜单显示log-->
				<div v-if="menuCollapsed">
					<n-gradient-text :size="20">
						<n-image width="40" :src="logoImage"></n-image>
					</n-gradient-text>
				</div>
				<!--展开菜单显示logo-->
				<div class="px-6" v-else>
					<div class="text-2xl">
						<n-gradient-text class="flex items-center">
							<n-image width="40" :src="logoImage" class="mr-3"></n-image>
							<span class="text-lg">Slow Admin</span>
						</n-gradient-text>
					</div>
				</div>
			</div>
			<!--侧边菜单-->
			<n-menu :options="menuOptions"
			        :render-label="renderMenuLabel"
			        :render-icon="renderMenuIcon"
			        v-model:value="router.currentRoute.value.name"
			        accordion
			        :class="{'px-2':menuCollapsed}" />
		</n-layout-sider>
		
		<!--右边的内容-->
		<n-layout>
			<!--头-->
			<n-layout-header style="height: 55px" class="flex items-center">
				<div class="flex w-full items-center h-full shadow z-10">
					<!--顶部菜单-左边-->
					<div class="flex-1 px-5 flex items-center">
						<!--点击收起/展开菜单-->
						<div class="cursor-pointer flex items-center" @click="menuCollapsed = !menuCollapsed">
							<n-tooltip trigger="hover">
								<template #trigger>
									<n-icon :component="MenuIcon" size="24"></n-icon>
								</template>
								{{ menuCollapsed ? "展开菜单" : "收起菜单" }}
							</n-tooltip>
						</div>
						<!--面包屑-->
						<div class="pl-5">
							<n-breadcrumb>
								<n-breadcrumb-item v-for="(item, index) in store.state.breadcrumb"
								                   :key="index"
								                   :href="'#' + item.router">
									{{ item.label }}
								</n-breadcrumb-item>
							</n-breadcrumb>
						</div>
					</div>
					<!--顶部菜单-右边-->
					<div class="w-80 flex items-center justify-end">
						<!--右侧工具栏-->
						<div class="pr-5">
							<n-space>
								<div class="flex items-center cursor-pointer">
									<n-popover trigger="hover" style="width: 240px">
										<template #trigger>
											<n-icon :component="colorIcon" size="18"></n-icon>
										</template>
										<n-color-picker :swatches="['#1890FF', '#2aae67', '#e1251b', '#18a058', '#ff5c00', '#14baf8', '#536DFE', '#546E7A']"
										                :modes="['rgb']"
										                :show-alpha="false"
										                :default-value="store.state.themeColor"
										                @update:value="changeThemeColor" />
									</n-popover>
								</div>
								<!--主题切换-->
								<div class="flex items-center cursor-pointer">
									<n-tooltip trigger="hover">
										<template #trigger>
											<n-icon :component="store.state.themeMode == 'dark' ? sunIcon : moonIcon"
											        size="18"
											        @click="toggleTheme"></n-icon>
										</template>
										{{ store.state.themeMode == "dark" ? "切换浅色主题" : "切换深色主题" }}
									</n-tooltip>
								</div>
							</n-space>
						</div>
						<!--用户信息-->
						<div class="flex items-center pr-2">
							<n-popover trigger="hover">
								<template #trigger>
									<div class="flex items-center cursor-pointer">
										<div class="">
											{{ user.name }}
										</div>
										<div class="px-3 flex items-center">
											<n-avatar
												round
												size="small"
												src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg" />
										</div>
									</div>
								</template>
								<template #header>
									<n-text strong depth="1" @click="goUserSetting">
										<span class="flex items-center p-1 cursor-pointer">
											<n-icon :component="UserIcon" class="mr-2"></n-icon>
											个人设置
										</span>
									</n-text>
								</template>
								<span class="flex items-center p-1 cursor-pointer" @click="logout">
									<n-icon :component="LogOutIcon" class="mr-2"></n-icon>
									退出登录
								</span>
							</n-popover>
						</div>
					</div>
				</div>
			</n-layout-header>
			
			<!--主体-->
			<n-layout content-style="padding: 15px;" :native-scrollbar="false" :embedded="true" class="content-body">
				<router-view v-slot="{ Component }">
					<transition name="custom-classes-transition"
					            mode="out-in"
					            appear
					            enter-active-class="animate__animated animate__fadeIn animate_duration_in"
					            leave-active-class="animate__animated animate__fadeOut animate_duration_out">
						<component :is="Component" />
					</transition>
				</router-view>
				<!--回到顶部-->
				<n-back-top :right="100" />
			</n-layout>
		</n-layout>
	</n-layout>
</template>

<script lang="ts" setup>
import {h, ref} from "vue"
import {NIcon, useDialog, useLoadingBar, useMessage} from "naive-ui"
import type {MenuOption} from "naive-ui"
import {RouterLink, useRouter} from "vue-router"
import {clearLoginInfo, getMenuInfo, getUserInfo} from "@/utils/common"
import {carbonIcon, ionicons5Icon} from "@/utils/icon"
import {useStore} from "vuex"
import logoImage from "@/assets/logo.png"

// 挂载naive组件的方法至window, 以便在路由钩子函数和请求函数里面调用
window.$loadingBar = useLoadingBar()
window.$dialog = useDialog()
window.$message = useMessage()

const UserIcon = carbonIcon("UserAvatar")
const LogOutIcon = ionicons5Icon("LogOutOutline")
const MenuIcon = ionicons5Icon("Menu")
const sunIcon = ionicons5Icon("SunnyOutline")
const moonIcon = carbonIcon("Moon")
const colorIcon = carbonIcon("ColorPalette")

const router = useRouter()
const store = useStore()

// 切换主题
const toggleTheme = () => {
	store.commit("toggleTheme")
}

// 改变主题颜色
const changeThemeColor = (color: string) => {
	store.commit("changeThemeColor", color)
}

// 是否收起菜单 true:收起
const menuCollapsed = ref(false)

// 处理菜单数据
const handleMenuData = (menus: any) => {
	menus.forEach((item: any, index: any) => {
		item.iconName = item.icon
		delete item.icon
		
		if (item.children) {
			handleMenuData(item.children)
		}
		
		if (item.show != 1) {
			menus.splice(index, 1)
		}
		if (item.children) {
			if (item.children.length == 0) {
				item.children = null
			}
		}
	})
	
	return menus
}

// 菜单
const menuOptions = handleMenuData(getMenuInfo())

// 批量渲染Label
const renderMenuLabel = (option: MenuOption) => {
	if (option.router) {
		return h(
			<any>RouterLink,
			{
				to: {path: option.router},
			},
			{default: () => option.label},
		)
	}
	
	if (option.href) {
		return h(
			"a",
			{href: option.href, target: "_blank"},
			option.label as string,
		)
	}
	
	return option.label as string
}

// 批量渲染菜单
const renderMenuIcon = (option: any) => {
	// 返回 falsy 值，不再渲染图标及占位符 -- false不占位 true占位
	if (typeof option.iconName == "undefined") return false
	
	let icon = ""
	if (option.icon_library == "carbon") {
		icon = carbonIcon(option.iconName)
	} else if (option.icon_library == "ionicons5") {
		icon = ionicons5Icon(option.iconName)
	}
	
	return h(NIcon, null, {default: () => h(icon)})
}

// 用户信息
const user = ref(getUserInfo())

// 前往用户设置
const goUserSetting = () => {
	router.push("/system/user-setting")
}

// 退出登录
const logout = () => {
	clearLoginInfo()
	
	router.replace({
		name: "login",
	})
}
</script>

<style lang="scss" scoped>
.content-body {
	height: calc(100% - 55px);
}

.animate_duration_in {
	animation-duration: .5s;
}

.animate_duration_out {
	animation-duration: .3s;
}
</style>
